/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.uniminuto.arqSw.videoMinuto.DAO;


import co.edu.uniminuto.arqSw.videoMinuto.Hibernate.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.hibernate.Query;
import org.hibernate.Transaction;
import co.edu.uniminuto.arqSw.videoMinuto.util.ParametrosGlobales;
import java.io.Serializable;
import java.util.logging.Logger;
import org.hibernate.Session;

/**
 *
 * @author Administrador
 */
public class VideoDAO extends GenericDAO {

    public static final Logger logger = Logger.getLogger(VideoDAO.class.getName());

    public VideoDAO() {
        super();
    }

    public boolean notIsEmptyString(String s) {
        if (s != null && !s.isEmpty() && !s.equalsIgnoreCase("0")) {
            return true;
        }
        return false;
    }

    public List<Video> getVideos(Hashtable<String, String> datos) {
        List<Video> misVideos = new ArrayList<Video>();
        try {


            /*
             * Este el el String QueryGeneral
             */
            String query = ""
                    + "                         From "
                    + "                            Video v "
                    + "                            {%FILTRO_IDIOMA_CLASES%}                     "
                    + "                            Join Fetch v.clasificacion c "
                    + "                            {%FILTRO_PERSONAS_CLASES%}                                 "
                    + "                            {%FILTRO_TIPO_CLASES%}               "
                    + "                            {%FILTRO_CALIFICACION_CLASES%}"
                    + "                            {%FILTRO_CATEGORIA_CLASES%}                                      "
                    + "                         Where "
                    + "                             c.idClasificacion={%FILTRO_CLASIFICACION%}"    
                    + "                             {%FILTRO_IDIOMA%} "
                    + "                             {%FILTRO_FECHAS%}"
                    + "                             {%FILTRO_DURACION%}                    "
                    + "                             {%FILTRO_TIPO%}"
                    + "                             {%FILTRO_CALIFICACION%} "
                    + "                             {%FILTRO_CATEGORIA%}"
                    + "                             {%FILTRO_PERSONAS%}     "
                    + "                                                          "
                    + "                             ";

           //datos.containsKey(ParametrosGlobales.FILTRO_IDIOMA);
            
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_ROL_PERSONA)) && notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_NOMBRE_PERSONA))){
                
                query = query.replace("{%FILTRO_PERSONAS_CLASES%}", "Join Fetch v.regPersonases reg");
                query = query.replace("{%FILTRO_PERSONAS%}", "And reg.persona.nomPersona like :nombrePersona And reg.tipoPersona.idTipoPersona=:tipoPersona");
                
                
            }
            else{
                
                query = query.replace("{%FILTRO_PERSONAS_CLASES%}", "");
                query = query.replace("{%FILTRO_PERSONAS%}", "");
                
            
            }
            
            /**
             * Si llega idioma
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_IDIOMA)) && notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_TIPO_IDIOMA))) {
                
                if(datos.get(ParametrosGlobales.FILTRO_TIPO_IDIOMA).equals("1")){
                  
                    query = query.replace("{%FILTRO_IDIOMA_CLASES%}", " Join Fetch v.idioma i");
                    //Join Fetch v.idioma i
                }
                else if(datos.get(ParametrosGlobales.FILTRO_TIPO_IDIOMA).equals("2")){
                    
                    query = query.replace("{%FILTRO_IDIOMA_CLASES%}", " Join Fetch v.idiomas i");
                }
                else if(datos.get(ParametrosGlobales.FILTRO_TIPO_IDIOMA).equals("3")){
                    query = query.replace("{%FILTRO_IDIOMA_CLASES%}", " Join Fetch v.idiomas_1 i");
                }
                
                query = query.replace("{%FILTRO_IDIOMA%}", "i.idIdioma=:idioma");
                
            } else {
                
                 query = query.replace("{%FILTRO_IDIOMA_CLASES%}", "");
                query = query.replace("{%FILTRO_IDIOMA%}", "");
            }
            
            
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CATEGORIA))){
                 query = query.replace("{%FILTRO_CATEGORIA_CLASES%}", " Join Fetch v.categorias cat ");
                 query = query.replace("{%FILTRO_CATEGORIA%}", " And cat.idCategoria in (:categorias)");
            }
            else{
                 query = query.replace("{%FILTRO_CATEGORIA_CLASES%}", "");
                 query = query.replace("{%FILTRO_CATEGORIA%}", "");
                
            }
            
            
            /*
             * Si llega calificación
             */
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CALIFICACION)) &&
               notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_INI)) &&
               notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_FIN))     
                    ){
                 query = query.replace("{%FILTRO_CALIFICACION_CLASES%}", " Join Fetch v.calificacions cal ");
                 query = query.replace("{%FILTRO_CALIFICACION%}", " And cal.tipoCalificacion.idTipoCalificacion=:calificacion And cal.cantCalificacion>=:califica_ini And cal.cantCalificacion<=:califica_fin ");
            }
            else{
                 query = query.replace("{%FILTRO_CALIFICACION_CLASES%}", "");
                 query = query.replace("{%FILTRO_CALIFICACION%}", "");
            
            }
            
            /**
             * Si llega duración del video
             */
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_INI)) &&
                    notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_FIN))){
                    query = query.replace("{%FILTRO_DURACION%}", "And v.duraVideo>=:duracion_ini And v.duraVideo<=:duracion_fin");
           
            }
            else{
                query = query.replace("{%FILTRO_DURACION%}", "");
            }
            
            /**
             * Si llega tipo de video a consultar
             */
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_TIPO_VIDEO))){
                
                if(datos.get(ParametrosGlobales.FILTRO_TIPO_VIDEO).equals("1")){
                    
                    query = query.replace("{%FILTRO_TIPO%}", "And p.idPelicula is not null");
                    query = query.replace("{%FILTRO_TIPO_CLASES%}", " Join Fetch v.peliculas p ");
                    
                }
                else if(datos.get(ParametrosGlobales.FILTRO_TIPO_VIDEO).equals("2")){
                    query = query.replace("{%FILTRO_TIPO%}", "And s.idSerie is not null");
                    query = query.replace("{%FILTRO_TIPO_CLASES%}", " Join Fetch v.series s");
                }
                else if(datos.get(ParametrosGlobales.FILTRO_TIPO_VIDEO).equals("3")){
                    query = query.replace("{%FILTRO_TIPO%}", "And col.idColeccion is not null");
                    query = query.replace("{%FILTRO_TIPO_CLASES%}", " Join Fetch v.coleccions col");
                }
                else if(datos.get(ParametrosGlobales.FILTRO_TIPO_VIDEO).equals("4")){
                    query = query.replace("{%FILTRO_TIPO%}", "");
                    query = query.replace("{%FILTRO_TIPO_CLASES%}", "");
                    //query = query.replace("{%FILTRO_TIPO%}", "And col.idColeccion is null And s.idSerie is null And p.idPelicula is null");                    
                }
                else{
                  query = query.replace("{%FILTRO_TIPO%}", "");
                  query = query.replace("{%FILTRO_TIPO_CLASES%}", "");
                }
            }
            else{
                  query = query.replace("{%FILTRO_TIPO%}", "");
                  query = query.replace("{%FILTRO_TIPO_CLASES%}", "");
            }
            
            
            /**
             * Si llega clasificación
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CLASIFICACION))) {
                query = query.replace("{%FILTRO_CLASIFICACION%}", ":clasificacion");
            } else {
                query = query.replace("{%FILTRO_CLASIFICACION%}", "c.idClasificacion");
            }

            
            /**
             * Si llegan fechas de producción
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION)) && notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION))) {
                query = query.replace("{%FILTRO_FECHAS%}", "And v.fechaProduccion >=:fecha_ini AND v.fechaProduccion<=:fecha_fin ");
            } else {
                query = query.replace("{%FILTRO_FECHAS%}", "");
            }

            
            
            Transaction tx = getSession().beginTransaction();
            Query q = getSession().createQuery(query);
            
            /**
             * Parametro para idioma
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_IDIOMA))) {
                q.setParameter("idioma", datos.get(ParametrosGlobales.FILTRO_IDIOMA));
            }
            
            
           if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_ROL_PERSONA)) && notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_NOMBRE_PERSONA))){
            
                  q.setParameter("nombrePersona", "%"+datos.get(ParametrosGlobales.FILTRO_NOMBRE_PERSONA)+"%");
                  q.setParameter("tipoPersona", datos.get(ParametrosGlobales.FILTRO_ROL_PERSONA));
  
           }

            
            
            /**
             * Parametros de la calificacion
             */
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CALIFICACION)) &&
               notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_INI)) &&
               notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_FIN))     
                    ){
                
                q.setParameter("calificacion", datos.get(ParametrosGlobales.FILTRO_CALIFICACION));
                q.setParameter("califica_ini", datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_INI));
                q.setParameter("califica_fin", datos.get(ParametrosGlobales.FILTRO_RANGO_CAL_FIN));
                
            }
            
            
            /**
             * Parametro para clasificación
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CLASIFICACION))) {
                q.setParameter("clasificacion", datos.get(ParametrosGlobales.FILTRO_CLASIFICACION));
            }
            
             if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_CATEGORIA))){
                 q.setParameter("categorias", datos.get(ParametrosGlobales.FILTRO_CATEGORIA));
                 
            }
            
            /**
             * Parametros de fechas de producción
             */
            if (notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION)) && notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION))) {
                q.setParameter("fecha_ini", datos.get(ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION));
                q.setParameter("fecha_fin", datos.get(ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION));
            }
            
            /**
             * Parametros derango de duración
             */
            if(notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_INI)) &&
                    notIsEmptyString(datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_FIN))){
                q.setParameter("duracion_ini", datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_INI));
                q.setParameter("duracion_fin", datos.get(ParametrosGlobales.FILTRO_RANGO_DURACION_FIN));
            }
            

            misVideos = (List<Video>) q.list();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return misVideos;
    }

    public List<Categoria> getCategorias() {

        List<Categoria> cats = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM Categoria");


            cats = (List<Categoria>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return cats;

    }

    public List<Idioma> getIdiomas() {

        List<Idioma> idiomas = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM Idioma");


            idiomas = (List<Idioma>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return idiomas;

    }

    public List<Clasificacion> getClasificacion() {

        List<Clasificacion> clasificaciones = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM Clasificacion");


            clasificaciones = (List<Clasificacion>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return clasificaciones;

    }

    public List<TipoCalificacion> getTipoCalificaciones() {
        List<TipoCalificacion> calificaciones = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM TipoCalificacion");


            calificaciones = (List<TipoCalificacion>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return calificaciones;
    }

    public List<Formato> getFormatos() {
        List<Formato> formatos = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM Formato");


            formatos = (List<Formato>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return formatos;
    }

    public List<TipoPersona> getRoles() {
        List<TipoPersona> roles = null;
        try {
            Transaction tx = this.getSession().beginTransaction();
            Query q = this.getSession().createQuery("FROM TipoPersona");


            roles = (List<TipoPersona>) q.list();


        } catch (Exception e) {

            e.printStackTrace();
        }
        return roles;
    }

    public List<Video> busqueda(Hashtable<String, String> datos) {
        List<Video> misVideos = new ArrayList<Video>();
        Set<String> keys = datos.keySet();
        Hashtable<String, String> tablas = new Hashtable<String, String>();

        String tabla = "", condicional = "", parameters = "", query = "";
        tablas.put("Video v", " ");
        for (String k : keys) {
            /*
             * if (k.equalsIgnoreCase(""+ParametrosGlobales.FILTRO_TIPO_VIDEO))
             * { if (Integer.parseInt(datos.get(k)) == 1) { //son peliculas
             * tablas.put("Pelicula p", " "); } else if
             * (Integer.parseInt(datos.get(k)) == 2) { //son series
             * tablas.put("Serie s", " "); } else if
             * (Integer.parseInt(datos.get(k)) == 3) { //son colecciones
             * tablas.put("Colecciones c", " "); } }
             *
             */

            /*if (k.equalsIgnoreCase("idioma")) {
             condicional += " v.idioma = :idioma AND";
             parameters += "idioma,";
             } else if (k.equalsIgnoreCase("idiomaDoblado")) {
             condicional += " v.idiomas_1 = :idioma AND";
             parameters += "idiomas_1,";
             } else if (k.equalsIgnoreCase("idiomaSubtitulado")) {
             condicional += " v.idiomas = :idioma AND";
             parameters += "idiomas,";
             }
             */
            if (k.equalsIgnoreCase(ParametrosGlobales.FILTRO_RANGO_DURACION_INI)) {
                condicional += " v.dura_video > :" + ParametrosGlobales.FILTRO_RANGO_DURACION_INI + " AND";
                parameters += ParametrosGlobales.FILTRO_RANGO_DURACION_INI + ",";
            }
            if (k.equalsIgnoreCase(ParametrosGlobales.FILTRO_RANGO_DURACION_FIN)) {
                condicional += " v.dura_video < :" + ParametrosGlobales.FILTRO_RANGO_DURACION_FIN + " AND";
                parameters += ParametrosGlobales.FILTRO_RANGO_DURACION_INI + ",";
            }
           /* if (k.equalsIgnoreCase(ParametrosGlobales.FILTRO_DURACION)) {
                condicional += " v.dura_video = :" + ParametrosGlobales.FILTRO_DURACION + " AND";
                parameters += ParametrosGlobales.FILTRO_DURACION + ",";
            }*/

            /*
             * if (k.equalsIgnoreCase("categoria")) { tablas.put("Categoria ca",
             * " "); condicional += " ca.id_categoria = :categoria AND";
             * parameters += "categoria,"; }
             */
            if (k.equalsIgnoreCase(ParametrosGlobales.FILTRO_ROL_PERSONA)) {
                tablas.put("v.regPersonases tp", " ");
                condicional += " tp.idTipoPersona = :" + ParametrosGlobales.FILTRO_ROL_PERSONA + " AND";
                parameters += ParametrosGlobales.FILTRO_ROL_PERSONA + ",";
            }
            if (k.equalsIgnoreCase("" + ParametrosGlobales.FILTRO_NOMBRE_PERSONA)) {
                tablas.put("v.regPersonases tp", " ");
                condicional += " tp.idTipoPersona = :" + ParametrosGlobales.FILTRO_NOMBRE_PERSONA + " AND";
                parameters += ParametrosGlobales.FILTRO_NOMBRE_PERSONA + ",";
            }
            if (k.equalsIgnoreCase("" + ParametrosGlobales.FILTRO_CLASIFICACION)) {
                tablas.put("lev.clasificacion cla", " ");
                condicional += " cla.idClasificacion = :" + ParametrosGlobales.FILTRO_CLASIFICACION + " AND";
                parameters += ParametrosGlobales.FILTRO_CLASIFICACION + ",";
            }
            //ParametrosGlobales.FILTRO_CALIFICACION
            //ParametrosGlobales.FILTRO_RANGO_CAL_INI < ParametrosGlobales.FILTRO_RANGO_CAL_FIN
            if (k.equalsIgnoreCase("" + ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION)) {
                condicional += " v.fechaProduccion >= to_date(:" + ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION + ") AND";
                parameters += ParametrosGlobales.FILTRO_FECHA_INI_PRODUCCION + ",";
            }
            if (k.equalsIgnoreCase("" + ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION)) {
                condicional += " v.fechaProduccion <= to_date(:" + ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION + ") AND";
                parameters += ParametrosGlobales.FILTRO_FECHA_FIN_PRODUCCION + ",";
            }
        }
        if (!datos.isEmpty()) {
            if (!tablas.isEmpty()) {
                boolean primero = true;
                boolean segundo = true;
                keys = tablas.keySet();
                for (String ke : keys) {
                    if (primero) {
                        tabla += ke + " ";
                    } else if (segundo) {
                        tabla += " JOIN FETCH " + ke;
                    } else {
                        tabla += " JOIN " + ke;
                    }
                }
            }
        }
        query = "From Video v";

        if (tablas.size() != 1) {
            if (!condicional.equals("")) {
                query = "v From " + tabla + " where " + condicional;
            } else {
                query = "v From Video v";
            }

        }
       
        Query q = getSession().createQuery(query);

        if (!parameters.equals("")) {
            String parametros[] = parameters.split(",");
            for (int i = 0; i < parametros.length; i++) {
                q.setParameter(parametros[i], datos.get(parametros[i]));
            }
        }
        misVideos = (List<Video>) q.list();

        return misVideos;
    }
    
    /**
     * Inserta el video y retorna el id de la insercion
     * @param video
     * @return 
     */
    public Serializable insertarVideo(Video video){
        Session session = null;
        try {
            session = this.getSession();
            Transaction tx = session.beginTransaction();
            Serializable id = session.save(video);
            tx.commit();
            return id;
        } catch (Exception e) {
            logger.info(e.toString() + " error insertar");
            return null;
        }finally{
            //if(session != null)session.close();
        }
    }
    public boolean eliminarVideo(Integer idVideo){
        try {
            Video v;
            Transaction tx = this.getSession().beginTransaction();
            v = (Video) this.getSession().load(Video.class,idVideo);
            this.getSession().delete(v);
            tx.commit();
            return true;
        } catch (Exception e) {
            return false;
        }finally{
            //if(session != null)session.close();
        }
    }
    
}
